Skip to content

libbpf-cargo: Relative anonymous type naming for struct fields #1178

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 28, 2025

Conversation

Waujito
Copy link
Contributor

@Waujito Waujito commented May 22, 2025

Previously, anonymous types were named as _anon{id} with id as a global counter. This approach caused cascading renaming of all subsequent anonymous definitions after any C anonymous struct order/amount change. This was a major design problem not for only development but even portability, since here may be the case when something was changed in vmlinux.h leading to compilation errors.

This PR addresses the issue by localizing cascading effects to the local struct layer rather than the global layer. While the solution is not fully ideal - cascading still occurs within individual structs - it eliminates the need for wide Rust code modifications when the order of anonymous struct definitions changes.

The PR is breaking and should be included in major version update.

The PR fixes #1161

While this approach is ok, I still think the better way will be to use getters, since this is breaking and less intuitive.

@danielocfb
Copy link
Collaborator

Haven't looked at it yet, but this is great. I was considering doing that for 0.25.0, but didn't have the cycles. Will postpone the release until I've gotten a chance to take a look here. Please look into the CI failures, which all seem legit.

Previously, anonymous types were named as __anon_{id} with id as a global counter. This approach caused cascading renaming of all subsequent anonymous definitions after any C anonymous struct order/amount change. This was a major design problem not for only development but even portability, since here may be the case when something was changed in vmlinux.h leading to compilation errors.

This commit addresses the issue by localizing cascading effects to the local struct layer rather than the global layer. While the solution is not fully ideal - cascading still occurs within individual structs - it eliminates the need for wide Rust code modifications when the order of anonymous struct definitions changes.

Note, that the commit does not fully eliminates __anon_{id}, but the most important part of it.

The commit is breaking and should be included in major version update.
@Waujito
Copy link
Contributor Author

Waujito commented May 22, 2025

Here are still some plain __anon types like in maps. I'll try to catch more and may be add some defenders of name collisions.

Copy link
Collaborator

@danielocfb danielocfb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general this seems okay to me, but the code seems under documented and under-tested in the sense that I can remove/change various lines and all tests keep passing. Similarly, I am not sure I understand some of the assignments done. Left some comments.

}

impl TypeMap {
pub fn derive_parent<'s>(&self, ty: &BtfType<'s>, parent: &BtfType<'s>) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub fn derive_parent<'s>(&self, ty: &BtfType<'s>, parent: &BtfType<'s>) {
fn derive_parent<'s>(&self, ty: &BtfType<'s>, parent: &BtfType<'s>) {

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the name really fitting? Aren't you more registering a parent relationship rather than "deriving" anything?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assign_parent?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps register_parent would fit?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@danielocfb danielocfb mentioned this pull request May 22, 2025
@danielocfb
Copy link
Collaborator

Here are still some plain __anon types like in maps. I'll try to catch more and may be add some defenders of name collisions.

What do you mean exactly? Where is "here"?

@Waujito
Copy link
Contributor Author

Waujito commented May 23, 2025

In 0e504e6 I simplified the code slightly, modified the global anon counting behavior, added documentation for new structure fields and included a test for depth-aligned anonymous structs.

The global anonymous struct counting now excludes relative anons to make its behavior more representative and easier to use. I also added some fallback protection on it for (im)possible case when global anonymous struct is assigned before a relative one: in such case we will use old type of naming.

Here are still some plain __anon types like in maps. I'll try to catch more and may be add some defenders of name collisions.

What do you mean exactly? Where is "here"?

Nvm. Those anonymous structs are at the global level and should be kept with old naming.

I think the code is ok now, but I'm aware of possible name collisions for relative types.
I can't mind the case, but what if. Maybe I should implement dep id counting in a separate hashmap for parent names as strings, but not with that crazy child_counter? This solution will not be elegant, but more trustworthy...

@danielocfb
Copy link
Collaborator

Thanks, it looks better now!

I think the code is ok now, but I'm aware of possible name collisions for relative types.
I can't mind the case, but what if.

Can you provide an example of such a case?

@Waujito
Copy link
Contributor Author

Waujito commented May 27, 2025

Can you provide an example of such a case?

I'm almost sure here is no the case. I was just thinking about it

Copy link
Collaborator

@danielocfb danielocfb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, thanks!

@danielocfb danielocfb merged commit 08563a6 into libbpf:master May 28, 2025
14 checks passed
danielocfb pushed a commit to d-e-s-o/libbpf-rs that referenced this pull request May 28, 2025
Add a CHANGELOG entry for pull request libbpf#1178, which adjusted the naming
of generated Rust types for anonymous C equivalents.

Signed-off-by: Daniel Müller <[email protected]>
danielocfb pushed a commit that referenced this pull request May 28, 2025
Add a CHANGELOG entry for pull request #1178, which adjusted the naming
of generated Rust types for anonymous C equivalents.

Signed-off-by: Daniel Müller <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

libbpf-cargo: Getters for struct fields
2 participants